home *** CD-ROM | disk | FTP | other *** search
- /*
- *****************************************************************
- * *
- * Section : Antic Display Modes *
- * Original Author : David Firth *
- * : Thomas Richter (thor) *
- * Date Written : 28th May 1995 *
- * : 17th February 1988 *
- * Version : 1.3 *
- * *
- * *
- * Description *
- * ----------- *
- * *
- * Section that handles Antic display modes. Not required *
- * for BASIC version. *
- * *
- *****************************************************************
- */
-
- #include <stdio.h>
- #include <string.h>
-
- #ifndef AMIGA
- #include "config.h"
- #endif
-
- #include "atari.h"
- #include "rt-config.h"
- #include "mem.h"
- #include "cpu.h"
- #include "gtia.h"
- #include "antic.h"
-
- #define FALSE 0
- #define TRUE 1
-
- int xmin;
- int xmax;
-
- int dmactl_xmin_noscroll;
- int dmactl_xmax_noscroll;
- static int dmactl_xmin_scroll;
- static int dmactl_xmax_scroll;
- static int memory_basis; /* refresh cycles needed for memory */
- static int pm_dma; /* DMA cycles needed by P/M graphics */
- static int char_delta;
- static int char_offset;
- static int invert_mask;
- static int blank_mask;
- static int screenaddr;
- #ifdef DEBUG
- static int hpos; /* identifier for horizontal position.
- used for debugging only. */
- #define H_BEFORE_DMA 1
- #define H_FIRST_HALF 2
- #define H_SECOND_HALF 3
- #define H_AFTER_WSYNC 4
- static int dlipos;
- static int dline;
- #endif
-
-
- /* colour lookup tables */
-
- static int lookup_f[256];
- static int lookup_4[256];
- static int lookup24[256];
- static int lookup_6[256];
- static int lookup_9[256];
-
- /* the scan line buffer of antic */
- static int scanbuf[64];
-
- /* A function that is used to build the graphics for a given line of
- the mode line.
- fillin is the pointer where to put the screen data in. Due to CPU
- limitations, THIS BUFFER MUST BE LONGWORD ALIGNED. To allow HSCROLLING,
- all this magic is done in the GTIA module, not here.
- width is the width of the scan line, in half color clocks.
- scanline is the scanline to be displayed, counts from zero up. */
-
- typedef void ModeFunc(UBYTE *fillin,int width,int scanline);
-
- static char *rcsid = "$Id: antic.c,v 1.30 1998/02/17 thor,david Exp $";
-
- UBYTE CHACTL;
- UBYTE CHBASE;
- UWORD DLIST,DLISTINIT;
- UBYTE DMACTL;
- UBYTE HSCROL;
- UBYTE NMIEN;
- UBYTE NMIST;
- UBYTE PMBASE;
- UBYTE VSCROL;
-
- int DMAwidth;
-
- extern UWORD regPC;
-
- /*
- * These are defined for Word (2 Byte) memory accesses. I have not
- * defined Longword (4 Byte) values since the Sparc architecture
- * requires that Longword are on a longword boundry.
- *
- * Words accesses don't appear to be a problem because the first
- * pixel plotted on a line will always be at an even offset, and
- * hence on a word boundry.
- *
- * Note: HSCROL is in colour clocks whereas the pixels are emulated
- * down to a half colour clock - the first pixel plotted is
- * moved across by 2*HSCROL
- */
-
- #define PF2_COLPF0 0x0404
- #define PF2_COLPF1 0x0505
- #define PF2_COLPF2 0x0606
- #define PF2_COLPF3 0x0707
- #define PF2_COLBK 0x0808
- #define PF2_COLPF1_FID 0x1515
-
- #define PF4_COLPF0 0x04040404
- #define PF4_COLPF1 0x05050505
- #define PF4_COLPF2 0x06060606
- #define PF4_COLPF3 0x07070707
- #define PF4_COLBK 0x08080808
- #define PF4_COLPF1_FID 0x15151515
-
- /* The middle of the display. All color/display/whatever changes BEFORE that
- cycle are seen on the same row.
- All changes after this color clock are visible ON THE NEXT row */
- #define CC_MIDDLE 50
- /* The propagation delay needed by the 6502 to react on the NMI interrupt */
- #define DLI_DELAY 8
- /* The number of cycles available on the same row to proceed after WSYNC and
- before the horizontal blank */
- #define AFTER_WSYNC 20
- /* The number of cycles available after the horizontal blank but before the
- DMA of antic actually starts */
- #define BEFORE_DMA 0
- /* The line where the VSYNC is generated. */
- #define VSYNC_POS 250
-
- int cc_middle=CC_MIDDLE;
- int dli_delay=DLI_DELAY;
- int after_wsync=AFTER_WSYNC;
- int before_dma=BEFORE_DMA;
- int vsync_pos=VSYNC_POS;
-
-
- int ypos;
-
- /*
- * Pre-computed values for improved performance
- */
-
- static int chbase_40; /* CHBASE for 40 character mode */
- static int chbase_20; /* CHBASE for 20 character mode */
- static int maddr_s; /* Address of Missiles - Single Line Resolution */
- static int p0addr_s; /* Address of Player0 - Single Line Resolution */
- static int p1addr_s; /* Address of Player1 - Single Line Resolution */
- static int p2addr_s; /* Address of Player2 - Single Line Resolution */
- static int p3addr_s; /* Address of Player3 - Single Line Resolution */
- static int maddr_d; /* Address of Missiles - Double Line Resolution */
- static int p0addr_d; /* Address of Player0 - Double Line Resolution */
- static int p1addr_d; /* Address of Player1 - Double Line Resolution */
- static int p2addr_d; /* Address of Player2 - Double Line Resolution */
- static int p3addr_d; /* Address of Player3 - Double Line Resolution */
-
- int wsync_halt = 0;
- static int carry=0; /* carry over of CPU cycles */
-
- /*
- =============================================================
- Define screen as ULONG to ensure that it is Longword aligned.
- This allows special optimisations under certain conditions.
- -------------------------------------------------------------
- The extra 16 scanlines is used as an overflow buffer and has
- enough room for any extra mode line. It is needed on the
- occasions that a valid JVB instruction is not found in the
- display list - An automatic break out will occur when ypos
- is greater than the ATARI_HEIGHT, if its one less than this
- there must be enough space for another mode line.
- =============================================================
- */
-
- ULONG *atari_screen = NULL;
- UBYTE *scrn_ptr;
-
- /* I/O register read */
-
- mtype ANTIC_CHBASE_GET(void)
- {
- return CHBASE;
- }
-
- mtype ANTIC_CHACTL_GET(void)
- {
- return CHACTL;
- }
-
- mtype ANTIC_DLISTL_GET(void)
- {
- return DLIST & 0xff;
- }
-
- mtype ANTIC_DLISTH_GET(void)
- {
- return DLIST >> 8;
- }
-
- mtype ANTIC_DMACTL_GET(void)
- {
- return DMACTL;
- }
-
- mtype ANTIC_VCOUNT_GET(void)
- {
- return ypos >> 1;
- }
-
- mtype ANTIC_NMIEN_GET(void)
- {
- return NMIEN | 0x1f;
- }
-
- mtype ANTIC_NMIST_GET(void)
- {
- return NMIST;
- }
-
- mtype ANTIC_WSYNC_GET(void)
- {
- if (wsync_halt)
- printf("Double wsync!\n");
- wsync_halt++;
- return 0xff;
- }
-
- /* I/O put routines */
-
- int ANTIC_CHBASE_PUT(mtype byte)
- {
- CHBASE = byte;
- chbase_40 = (byte << 8) & 0xfc00;
- chbase_20 = (byte << 8) & 0xfe00;
- #ifdef DEBUG
- printf("CHBASE = %x, ypos %d, hpos state %d, dlipos %d dline %d\n",byte,ypos,hpos,dlipos,dline);
- #endif
- return FALSE;
- }
-
- int ANTIC_CHACTL_PUT(mtype byte)
- {
- CHACTL = byte;
- /*
- =================================================================
- Check for vertical reflect, video invert and character blank bits
- =================================================================
- */
- switch (CHACTL & 0x07)
- {
- case 0x00 :
- char_offset = 0;
- char_delta = 1;
- invert_mask = 0x00;
- blank_mask = 0x00;
- break;
- case 0x01 :
- char_offset = 0;
- char_delta = 1;
- invert_mask = 0x00;
- blank_mask = 0x80;
- break;
- case 0x02 :
- char_offset = 0;
- char_delta = 1;
- invert_mask = 0x80;
- blank_mask = 0x00;
- break;
- case 0x03 :
- char_offset = 0;
- char_delta = 1;
- invert_mask = 0x80;
- blank_mask = 0x80;
- break;
- case 0x04 :
- char_offset = 7;
- char_delta = -1;
- invert_mask = 0x00;
- blank_mask = 0x00;
- break;
- case 0x05 :
- char_offset = 7;
- char_delta = -1;
- invert_mask = 0x00;
- blank_mask = 0x80;
- break;
- case 0x06 :
- char_offset = 7;
- char_delta = -1;
- invert_mask = 0x80;
- blank_mask = 0x00;
- break;
- case 0x07 :
- char_offset = 7;
- char_delta = -1;
- invert_mask = 0x80;
- blank_mask = 0x80;
- break;
- }
-
- return FALSE;
- }
-
- int ANTIC_DLISTL_PUT(mtype byte)
- {
- DLIST = (DLIST & 0xff00) | byte;
- DLISTINIT = DLIST;
- return FALSE;
- }
-
- int ANTIC_DLISTH_PUT(mtype byte)
- {
- DLIST = (DLIST & 0x00ff) | (byte<<8);
- DLISTINIT = DLIST;
- return FALSE;
- }
-
- int ANTIC_DMACTL_PUT(mtype byte)
- {
- /* printf("DMACTL set to %2x at %4x\n",byte,regPC); */
- DMACTL = byte;
- switch (DMACTL & 0x03)
- {
- case 0x00 :
- dmactl_xmin_noscroll = dmactl_xmax_noscroll = 0;
- dmactl_xmin_scroll = dmactl_xmax_scroll = 0;
- DMAwidth = 0;
- memory_basis = 9; /* nine cycles for refresh */
- break;
- case 0x01 :
- dmactl_xmin_noscroll = 64;
- dmactl_xmax_noscroll = ATARI_WIDTH - 64;
- dmactl_xmin_scroll = 32;
- dmactl_xmax_scroll = ATARI_WIDTH - 32;
- DMAwidth = 4;
- memory_basis = 2; /* nine cycles for refresh */
- break;
- case 0x02 :
- dmactl_xmin_noscroll = 32;
- dmactl_xmax_noscroll = ATARI_WIDTH - 32;
- dmactl_xmin_scroll = 0;
- dmactl_xmax_scroll = ATARI_WIDTH;
- memory_basis = 1;
- DMAwidth = 5;
- break;
- case 0x03 :
- dmactl_xmin_noscroll = dmactl_xmin_scroll = 0;
- dmactl_xmax_noscroll = dmactl_xmax_scroll = ATARI_WIDTH;
- memory_basis = 0;
- DMAwidth = 6;
- break;
- }
-
- pm_dma = 0; /* cycles needed for PM graphics */
-
- if (DMACTL & 0x0C) /* Player DMA enables missile DMA */
- pm_dma += 1;
- if (DMACTL & 0x08) /* Player DMA ? */
- pm_dma += 4;
-
- /* SingleLine DMACTL & 0x10 not covered here */
-
- return FALSE;
- }
-
- int ANTIC_HSCROL_PUT(mtype byte)
- {
- HSCROL = byte & 0x0f;
- return FALSE;
- }
-
- int ANTIC_NMIEN_PUT(mtype byte)
- {
- NMIEN = byte | 0x1f;
- /* printf("Wrote %d into NMIEN.\n",byte); */
- return FALSE;
- }
-
- int ANTIC_NMIRES_PUT(mtype byte)
- {
- NMIST = 0x1f;
- return FALSE;
- }
-
- int ANTIC_PMBASE_PUT(mtype byte)
- {
- UWORD pmbase_s;
- UWORD pmbase_d;
-
- PMBASE = byte;
-
- pmbase_s = (PMBASE & 0xf8) << 8;
- pmbase_d = (PMBASE & 0xfc) << 8;
-
- maddr_s = pmbase_s + 768;
- p0addr_s = pmbase_s + 1024;
- p1addr_s = pmbase_s + 1280;
- p2addr_s = pmbase_s + 1536;
- p3addr_s = pmbase_s + 1792;
-
- maddr_d = pmbase_d + 384;
- p0addr_d = pmbase_d + 512;
- p1addr_d = pmbase_d + 640;
- p2addr_d = pmbase_d + 768;
- p3addr_d = pmbase_d + 896;
-
- return FALSE;
- }
-
- int ANTIC_VSCROL_PUT(mtype byte)
- {
- VSCROL = byte & 0x0f;
- return FALSE;
- }
-
- int ANTIC_WSYNC_PUT(mtype byte)
- {
- wsync_halt ++;
- return TRUE;
- }
-
- void Init_Antic (int *argc, char *argv[],int base)
- {
- int i;
- int j;
-
- if (argc) {
- for (i=j=1;i<*argc;i++)
- {
- if (strcmp(argv[i],"-xcolpf1") == 0)
- enable_xcolpf1 = TRUE;
- else
- argv[j++] = argv[i];
- }
-
- *argc = j;
- }
-
- NMIEN = 0x1f;
- NMIST = 0x00;
- DMACTL = 0x00;
- VSCROL = 0x00;
- HSCROL = 0x00;
-
- /* setup lookup tables */
-
- memset(lookup_f,0,256*sizeof(int));
- memset(lookup_4,0,256*sizeof(int));
- memset(lookup24,0,256*sizeof(int));
- memset(lookup_9,0,256*sizeof(int));
-
- lookup_f[0x00]=PF_COLPF2;
- lookup_f[0x80]=lookup_f[0x40]=lookup_f[0x20]=
- lookup_f[0x10]=lookup_f[0x08]=lookup_f[0x04]=
- lookup_f[0x02]=lookup_f[0x01]=PF_COLPF1_FID;
-
- lookup_4[0x00]=PF4_COLBK;
- lookup_4[0x40]=lookup_4[0x10]=lookup_4[0x04]=lookup_4[0x01]=PF4_COLPF0;
- lookup_4[0x80]=lookup_4[0x20]=lookup_4[0x08]=lookup_4[0x02]=PF4_COLPF1;
- lookup_4[0xc0]=lookup_4[0x30]=lookup_4[0x0c]=lookup_4[0x03]=PF4_COLPF2;
-
- lookup24[0x00]=PF2_COLBK;
- lookup24[0x40]=lookup24[0x10]=lookup24[0x04]=lookup24[0x01]=PF2_COLPF0;
- lookup24[0x80]=lookup24[0x20]=lookup24[0x08]=lookup24[0x02]=PF2_COLPF1;
- lookup24[0xc0]=lookup24[0x30]=lookup24[0x0c]=lookup24[0x03]=PF2_COLPF3;
-
- lookup_9[0x00]=PF4_COLBK;
- lookup_9[0x80]=lookup_9[0x40]=lookup_9[0x20]=lookup_9[0x10]=
- lookup_9[0x08]=lookup_9[0x04]=lookup_9[0x02]=lookup_9[0x01]=PF4_COLPF0;
-
- memset(lookup_6+0x00,PF2_COLPF0,0x40*sizeof(int));
- memset(lookup_6+0x40,PF2_COLPF1,0x40*sizeof(int));
- memset(lookup_6+0x80,PF2_COLPF2,0x40*sizeof(int));
- memset(lookup_6+0xc0,PF2_COLPF3,0x40*sizeof(int));
-
- SetHW(base+_DMACTL,0xff0f,&ANTIC_DMACTL_GET,&ANTIC_DMACTL_PUT);
- SetHW(base+_CHACTL,0xff0f,&ANTIC_CHACTL_GET,&ANTIC_CHACTL_PUT);
- SetHW(base+_DLISTL,0xff0f,&ANTIC_DLISTL_GET,&ANTIC_DLISTL_PUT);
- SetHW(base+_DLISTH,0xff0f,&ANTIC_DLISTH_GET,&ANTIC_DLISTH_PUT);
- SetHW(base+_HSCROL,0xff0f,NULL,&ANTIC_HSCROL_PUT);
- SetHW(base+_VSCROL,0xff0f,NULL,&ANTIC_VSCROL_PUT);
- SetHW(base+_PMBASE,0xff0f,NULL,&ANTIC_PMBASE_PUT);
- SetHW(base+_CHBASE,0xff0f,&ANTIC_CHBASE_GET,&ANTIC_CHBASE_PUT);
- SetHW(base+_VCOUNT,0xff0f,&ANTIC_VCOUNT_GET,NULL);
- SetHW(base+_NMIEN,0xff0f,&ANTIC_NMIEN_GET,&ANTIC_NMIEN_PUT);
- SetHW(base+_NMIRES,0xff0f,&ANTIC_NMIST_GET,&ANTIC_NMIRES_PUT);
- SetHW(base+_WSYNC,0xff0f,&ANTIC_WSYNC_GET,&ANTIC_WSYNC_PUT);
- }
-
- /********************************************************************
- ** Antic Mode line generators **
- ** **
- ** These functions come in pairs. One is used to fill the antic **
- ** scan line buffer scanbuf[] and is called once for each mode **
- ** line. It returns a function pointer for the second function **
- ** of the pair, used to build the actual scan lines. They take an **
- ** integer as argument that defines which scan line of the mode **
- ** line should be build - as needed by vertical scrolling. **
- ** Horizontal scrolling, however, is done elsewhere, in the GTIA **
- ** buffer. That looks rather wierd, but allows optimized **
- ** long accesses here. **
- ********************************************************************/
-
- /*
- * Builder pair for blank lines
- */
-
- void Build_Blank(UBYTE *fillin,int width,int scanline)
- {
- memset(fillin,PF_COLBK,width);
- }
-
- ModeFunc *Antic_Blank(void)
- {
- return &Build_Blank;
- }
-
- /*
- * Builder pair for Antic_2
- */
-
- void Build_Antic_2(UBYTE *ptr,int width,int scanline)
- {
- int chaddr;
- int i;
- int nchars = width >> 3;
- int *scan=scanbuf;
- int screendata;
- int chbase;
- int chdata;
-
- chbase = chbase_40 + char_offset + scanline*char_delta;
-
- for (i=0;i<nchars;i++,scan++) {
-
- /* get character data */
- screendata = *scan;
-
- /* get character base address */
- chaddr = chbase + ((screendata & 0x7f) << 3);
-
- /* get character data */
- chdata = APeek(chaddr);
-
- if (screendata & invert_mask)
- chdata ^= 0xff;
-
- if (screendata & blank_mask)
- chdata = 0;
-
- if (chdata) {
- *ptr++ = lookup_f[chdata & 0x80];
- *ptr++ = lookup_f[chdata & 0x40];
- *ptr++ = lookup_f[chdata & 0x20];
- *ptr++ = lookup_f[chdata & 0x10];
- *ptr++ = lookup_f[chdata & 0x08];
- *ptr++ = lookup_f[chdata & 0x04];
- *ptr++ = lookup_f[chdata & 0x02];
- *ptr++ = lookup_f[chdata & 0x01];
- } else {
- /* Since HSCROLL is always done in the GTIA module, this is aligned ! */
- ULONG *l_ptr = (ULONG*)ptr;
-
- *l_ptr++ = PF4_COLPF2;
- *l_ptr++ = PF4_COLPF2;
-
- ptr = (UBYTE*)l_ptr;
- }
- }
- }
-
- ModeFunc *Antic_2(int width)
- {
- int i;
- int *scan=scanbuf;
- int nchars = width >> 3;
-
- for(i=0;i<nchars;i++,scan++,screenaddr++)
- *scan=APeek(screenaddr);
-
- return &Build_Antic_2;
- }
-
- /*
- * Builder pair for Antic 3
- */
-
- void Build_Antic_3(UBYTE *ptr,int width,int scanline)
- {
- int chaddr;
- int i;
- int nchars = width >> 3;
- int *scan=scanbuf;
- int screendata;
- int chdata=0;
-
- for (i=0;i<nchars;i++,scan++) {
-
- /* get character data */
- screendata = *scan;
-
- if ((screendata & 0x60) == 0x60) {
- /* This is a lowercase character. This means that the first two
- scan lines are blank and get mirrored as the last two scan lines */
- switch(scanline) {
- case 0:
- case 1:
- chdata = 0;
- break;
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- chaddr = chbase_40 + char_offset + scanline*char_delta;
- chdata = APeek(chaddr);
- break;
- case 8:
- chaddr = chbase_40 + char_offset;
- chdata = APeek(chaddr);
- break;
- case 9:
- chaddr = chbase_40 + char_offset + char_delta;
- chdata = APeek(chaddr);
- break;
- }
- } else {
- /* Uppercase character. We use the standard orientation and keep the
- last two scan lines blank */
- if (scanline<8) {
- chaddr = chbase_40 + char_offset + char_delta * scanline;
- chdata = APeek(chaddr);
- } else {
- chdata = 0;
- }
- }
-
- if (screendata & invert_mask)
- chdata ^= 0xff;
-
- if (screendata & blank_mask)
- chdata = 0;
-
- if (chdata) {
- *ptr++ = lookup_f[chdata & 0x80];
- *ptr++ = lookup_f[chdata & 0x40];
- *ptr++ = lookup_f[chdata & 0x20];
- *ptr++ = lookup_f[chdata & 0x10];
- *ptr++ = lookup_f[chdata & 0x08];
- *ptr++ = lookup_f[chdata & 0x04];
- *ptr++ = lookup_f[chdata & 0x02];
- *ptr++ = lookup_f[chdata & 0x01];
- } else {
- /* Since HSCROLL is always done in the GTIA module, this is aligned ! */
- ULONG *l_ptr = (ULONG*)ptr;
-
- *l_ptr++ = PF4_COLPF2;
- *l_ptr++ = PF4_COLPF2;
-
- ptr = (UBYTE*)l_ptr;
- }
- }
- }
-
- ModeFunc *Antic_3(int width)
- {
- int i;
- int *scan=scanbuf;
- int nchars = width >> 3;
-
- for(i=0;i<nchars;i++,scan++,screenaddr++)
- *scan=APeek(screenaddr);
-
- return &Build_Antic_3;
- }
-
-
- /*
- * Display Builders for Antic Mode 4
- */
-
- void Build_Antic_4(UBYTE *b_ptr,int width,int scanline)
- {
- int chaddr;
- int i;
- int nchars = width >> 3;
- int *scan=scanbuf;
- int screendata;
- int chbase;
- int chdata;
- int *lookup;
- UWORD *ptr=(UWORD *)b_ptr;
-
- chbase = chbase_40 + char_offset + scanline*char_delta;
-
- for (i=0;i<nchars;i++,scan++) {
-
- /* get character data */
- screendata = *scan;
-
- /* get character base address */
- chaddr = chbase + ((screendata & 0x7f) << 3);
-
- /* get character data */
- chdata = APeek(chaddr);
-
- if (screendata & 0x80)
- lookup = lookup24;
- else
- lookup = lookup_4;
-
- if (chdata) {
- *ptr++ = lookup[chdata & 0xc0];
- *ptr++ = lookup[chdata & 0x30];
- *ptr++ = lookup[chdata & 0x0c];
- *ptr++ = lookup[chdata & 0x03];
- } else {
- *ptr++ = PF2_COLBK;
- *ptr++ = PF2_COLBK;
- *ptr++ = PF2_COLBK;
- *ptr++ = PF2_COLBK;
- }
- }
- }
-
- ModeFunc *Antic_4(int width)
- {
- int i;
- int *scan=scanbuf;
- int nchars = width >> 3;
-
- for(i=0;i<nchars;i++,scan++,screenaddr++)
- *scan=APeek(screenaddr);
-
- return &Build_Antic_4;
- }
-
- /*
- * Builder Pair for Antic Mode 5
- */
-
- void Build_Antic_5(UBYTE *b_ptr,int width,int scanline)
- {
- int chaddr;
- int i;
- int nchars = width >> 3;
- int *scan=scanbuf;
- int screendata;
- int chbase;
- int chdata;
- int *lookup;
- UWORD *ptr=(UWORD *)b_ptr;
-
- chbase = chbase_40 + char_offset + (scanline>>1)*char_delta;
-
- for (i=0;i<nchars;i++,scan++) {
-
- /* get character data */
- screendata = *scan;
-
- /* get character base address */
- chaddr = chbase + ((screendata & 0x7f) << 3);
-
- /* get character data */
- chdata = APeek(chaddr);
-
- if (screendata & 0x80)
- lookup = lookup24;
- else
- lookup = lookup_4;
-
- if (chdata) {
- *ptr++ = lookup[chdata & 0xc0];
- *ptr++ = lookup[chdata & 0x30];
- *ptr++ = lookup[chdata & 0x0c];
- *ptr++ = lookup[chdata & 0x03];
- } else {
- *ptr++ = PF2_COLBK;
- *ptr++ = PF2_COLBK;
- *ptr++ = PF2_COLBK;
- *ptr++ = PF2_COLBK;
- }
- }
- }
-
- ModeFunc *Antic_5(int width)
- {
- int i;
- int *scan=scanbuf;
- int nchars = width >> 3;
-
- for(i=0;i<nchars;i++,scan++,screenaddr++)
- *scan=APeek(screenaddr);
-
- return &Build_Antic_5;
- }
-
-
- /*
- * Display Pair for Antic Mode 6
- */
-
- void Build_Antic_6(UBYTE *b_ptr,int width,int scanline)
- {
- int chaddr;
- int i;
- int nchars = width >> 4;
- int *scan=scanbuf;
- int screendata;
- int chbase;
- int chdata;
- int color;
- UWORD *ptr=(UWORD *)b_ptr;
-
- chbase = chbase_20 + char_offset + scanline*char_delta;
-
- for (i=0;i<nchars;i++,scan++) {
-
- /* get character data */
- screendata = *scan;
-
- /* get character base address */
- chaddr = chbase + ((screendata & 0x3f) << 3);
-
- /* get character cell color */
- color = lookup_6[screendata];
-
- /* get character data */
- chdata = APeek(chaddr);
-
- if (chdata) {
- *ptr++ = (chdata & 0x80)?(color):(PF2_COLBK);
- *ptr++ = (chdata & 0x40)?(color):(PF2_COLBK);
- *ptr++ = (chdata & 0x20)?(color):(PF2_COLBK);
- *ptr++ = (chdata & 0x10)?(color):(PF2_COLBK);
- *ptr++ = (chdata & 0x08)?(color):(PF2_COLBK);
- *ptr++ = (chdata & 0x04)?(color):(PF2_COLBK);
- *ptr++ = (chdata & 0x02)?(color):(PF2_COLBK);
- *ptr++ = (chdata & 0x01)?(color):(PF2_COLBK);
- } else {
- /* Since HSCROLL is always done in the GTIA module, this is aligned ! */
- ULONG *l_ptr = (ULONG*)ptr;
-
- *l_ptr++ = PF4_COLBK;
- *l_ptr++ = PF4_COLBK;
- *l_ptr++ = PF4_COLBK;
- *l_ptr++ = PF4_COLBK;
-
- ptr = (UWORD*)l_ptr;
- }
- }
- }
-
- ModeFunc *Antic_6(int width)
- {
- int i;
- int *scan=scanbuf;
- int nchars = width >> 4;
-
- for(i=0;i<nchars;i++,scan++,screenaddr++)
- *scan=APeek(screenaddr);
-
- return &Build_Antic_6;
- }
-
- /*
- * Display Pair for Antic Mode 7
- */
- void Build_Antic_7(UBYTE *b_ptr,int width,int scanline)
- {
- int chaddr;
- int i;
- int nchars = width >> 4;
- int *scan=scanbuf;
- int screendata;
- int chbase;
- int chdata;
- int color;
- UWORD *ptr=(UWORD *)b_ptr;
-
- chbase = chbase_20 + char_offset + (scanline>>1)*char_delta;
-
- for (i=0;i<nchars;i++,scan++) {
-
- /* get character data */
- screendata = *scan;
-
- /* get character base address */
- chaddr = chbase + ((screendata & 0x3f) << 3);
-
- /* get character cell color */
- color = lookup_6[screendata];
-
- /* get character data */
- chdata = APeek(chaddr);
-
- if (chdata) {
- *ptr++ = (chdata & 0x80)?(color):(PF2_COLBK);
- *ptr++ = (chdata & 0x40)?(color):(PF2_COLBK);
- *ptr++ = (chdata & 0x20)?(color):(PF2_COLBK);
- *ptr++ = (chdata & 0x10)?(color):(PF2_COLBK);
- *ptr++ = (chdata & 0x08)?(color):(PF2_COLBK);
- *ptr++ = (chdata & 0x04)?(color):(PF2_COLBK);
- *ptr++ = (chdata & 0x02)?(color):(PF2_COLBK);
- *ptr++ = (chdata & 0x01)?(color):(PF2_COLBK);
- } else {
- /* Since HSCROLL is always done in the GTIA module, this is aligned ! */
- ULONG *l_ptr = (ULONG*)ptr;
-
- *l_ptr++ = PF4_COLBK;
- *l_ptr++ = PF4_COLBK;
- *l_ptr++ = PF4_COLBK;
- *l_ptr++ = PF4_COLBK;
-
- ptr = (UWORD*)l_ptr;
- }
- }
- }
-
- ModeFunc *Antic_7(int width)
- {
- int i;
- int *scan=scanbuf;
- int nchars = width >> 4;
-
- for(i=0;i<nchars;i++,scan++,screenaddr++)
- *scan=APeek(screenaddr);
-
- return &Build_Antic_7;
- }
-
- /*
- * Function to Display Antic Mode 8
- */
-
- void Build_Antic_8(UBYTE *ptr,int width,int scanline)
- {
- int i;
- int nchars = width >> 5;
- int *scan = scanbuf;
- int screendata;
-
- for(i=0;i<nchars;i++,scan++) {
-
- screendata = *scan;
-
- memset(ptr,lookup_4[screendata & 0xc0],8);
- ptr += 8;
- memset(ptr,lookup_4[screendata & 0x30],8);
- ptr += 8;
- memset(ptr,lookup_4[screendata & 0x0c],8);
- ptr += 8;
- memset(ptr,lookup_4[screendata & 0x03],8);
- ptr += 8;
- }
- }
-
- ModeFunc *Antic_8(int width)
- {
- int i;
- int *scan=scanbuf;
- int nchars = width >> 5;
-
- for(i=0;i<nchars;i++,scan++,screenaddr++)
- *scan=APeek(screenaddr);
-
- return &Build_Antic_8;
- }
-
- /*
- * Display pair for Antic Mode 9
- */
-
- void Build_Antic_9(UBYTE *b_ptr,int width,int scanline)
- {
- int i;
- int nchars = width >> 5;
- int *scan = scanbuf;
- int screendata;
- ULONG *ptr = (ULONG *)(b_ptr);
-
- for(i=0;i<nchars;i++,scan++) {
-
- screendata = *scan;
-
- *ptr++=lookup_9[screendata & 0x80];
- *ptr++=lookup_9[screendata & 0x40];
- *ptr++=lookup_9[screendata & 0x20];
- *ptr++=lookup_9[screendata & 0x10];
- *ptr++=lookup_9[screendata & 0x08];
- *ptr++=lookup_9[screendata & 0x04];
- *ptr++=lookup_9[screendata & 0x02];
- *ptr++=lookup_9[screendata & 0x01];
- }
- }
-
- ModeFunc *Antic_9(int width)
- {
- int i;
- int *scan=scanbuf;
- int nchars = width >> 5;
-
- for(i=0;i<nchars;i++,scan++,screenaddr++)
- *scan=APeek(screenaddr);
-
- return &Build_Antic_9;
- }
-
- /*
- * Function to Display Antic Mode a
- */
-
- void Build_Antic_A(UBYTE *b_ptr,int width,int scanline)
- {
- int i;
- int nchars = width >> 4;
- int *scan = scanbuf;
- int screendata;
- ULONG *ptr=(ULONG *)b_ptr;
-
- for(i=0;i<nchars;i++,scan++) {
-
- screendata = *scan;
-
- *ptr++=lookup_4[screendata & 0xc0];
- *ptr++=lookup_4[screendata & 0x30];
- *ptr++=lookup_4[screendata & 0x0c];
- *ptr++=lookup_4[screendata & 0x03];
- }
- }
-
- ModeFunc *Antic_A(int width)
- {
- int i;
- int *scan=scanbuf;
- int nchars = width >> 4;
-
- for(i=0;i<nchars;i++,scan++,screenaddr++)
- *scan=APeek(screenaddr);
-
- return &Build_Antic_A;
- }
-
-
- /*
- * Function to Display Antic Mode b
- */
-
- void Build_Antic_B(UBYTE *b_ptr,int width,int scanline)
- {
- int i;
- int nchars = width >> 4;
- int *scan = scanbuf;
- int screendata;
- UWORD *ptr = (UWORD *)(b_ptr);
-
- for(i=0;i<nchars;i++,scan++) {
-
- screendata = *scan;
-
- *ptr++=lookup_9[screendata & 0x80];
- *ptr++=lookup_9[screendata & 0x40];
- *ptr++=lookup_9[screendata & 0x20];
- *ptr++=lookup_9[screendata & 0x10];
- *ptr++=lookup_9[screendata & 0x08];
- *ptr++=lookup_9[screendata & 0x04];
- *ptr++=lookup_9[screendata & 0x02];
- *ptr++=lookup_9[screendata & 0x01];
- }
- }
-
- ModeFunc *Antic_B(int width)
- {
- int i;
- int *scan=scanbuf;
- int nchars = width >> 4;
-
- for(i=0;i<nchars;i++,scan++,screenaddr++)
- *scan=APeek(screenaddr);
-
- return &Build_Antic_B;
- }
-
- /*
- * Function to Display Antic Mode c
- */
-
- ModeFunc *Antic_C(int width)
- {
- int i;
- int *scan=scanbuf;
- int nchars = width >> 4;
-
- for(i=0;i<nchars;i++,scan++,screenaddr++)
- *scan=APeek(screenaddr);
-
- return &Build_Antic_B;
- /* The scan lines of modes C & B look identically */
- }
-
-
- /*
- * Function to Display Antic Mode d
- */
-
- void Build_Antic_D(UBYTE *b_ptr,int width,int scanline)
- {
- int i;
- int nchars = width >> 3;
- int *scan = scanbuf;
- int screendata;
- UWORD *ptr=(UWORD *)b_ptr;
-
- for(i=0;i<nchars;i++,scan++) {
-
- screendata = *scan;
-
- *ptr++=lookup_4[screendata & 0xc0];
- *ptr++=lookup_4[screendata & 0x30];
- *ptr++=lookup_4[screendata & 0x0c];
- *ptr++=lookup_4[screendata & 0x03];
-
- }
- }
-
- ModeFunc *Antic_D(int width)
- {
- int i;
- int *scan=scanbuf;
- int nchars = width >> 3;
-
- for(i=0;i<nchars;i++,scan++,screenaddr++)
- *scan=APeek(screenaddr);
-
- return &Build_Antic_D;
- }
-
- /*
- * Function to display Antic Mode e
- */
-
- ModeFunc *Antic_E(int width)
- {
- int i;
- int *scan=scanbuf;
- int nchars = width >> 3;
-
- for(i=0;i<nchars;i++,scan++,screenaddr++)
- *scan=APeek(screenaddr);
-
- return &Build_Antic_D;
- /* The mode lines of modes E & D look alike */
- }
-
- /*
- * Function to display Antic Mode f
- */
-
- void Build_Antic_F(UBYTE *ptr,int width,int scanline)
- {
- int i;
- int nchars = width >> 3;
- int *scan = scanbuf;
- int screendata;
-
- for(i=0;i<nchars;i++,scan++) {
-
- screendata = *scan;
-
- *ptr++=lookup_f[screendata & 0x80];
- *ptr++=lookup_f[screendata & 0x40];
- *ptr++=lookup_f[screendata & 0x20];
- *ptr++=lookup_f[screendata & 0x10];
- *ptr++=lookup_f[screendata & 0x08];
- *ptr++=lookup_f[screendata & 0x04];
- *ptr++=lookup_f[screendata & 0x02];
- *ptr++=lookup_f[screendata & 0x01];
- }
- }
-
- ModeFunc *Antic_F(int width)
- {
- int i;
- int *scan=scanbuf;
- int nchars = width >> 3;
-
- for(i=0;i<nchars;i++,scan++,screenaddr++)
- *scan=APeek(screenaddr);
-
- return &Build_Antic_F;
- }
-
-
- /*
- *****************************************************************
- * *
- * Section : Display List *
- * Original Author : David Firth *
- * Date Written : 28th May 1995 *
- * Version : 1.0 *
- * *
- * Description *
- * ----------- *
- * *
- * Section that handles Antic Display List. Not required for *
- * BASIC version. *
- * *
- *****************************************************************
- */
-
- void pmg_dma (void)
- {
- int yhalf = ypos >> 1;
- /* single line shift not yet implemented.... */
-
- if (DMACTL & 0x08)
- {
- if (DMACTL & 0x10)
- {
- GRAFP0 = memory[p0addr_s + ypos];
- GRAFP1 = memory[p1addr_s + ypos];
- GRAFP2 = memory[p2addr_s + ypos];
- GRAFP3 = memory[p3addr_s + ypos];
- }
- else
- {
- GRAFP0 = memory[p0addr_d + yhalf - delayp0];
- GRAFP1 = memory[p1addr_d + yhalf - delayp1];
- GRAFP2 = memory[p2addr_d + yhalf - delayp2];
- GRAFP3 = memory[p3addr_d + yhalf - delayp3];
- }
- }
-
- if (DMACTL & 0x0C) /* Player DMA enables missile DMA as well */
- {
- if (DMACTL & 0x10)
- GRAFM = memory[maddr_s + ypos];
- else {
- int mis0,mis1,mis2,mis3;
-
- mis0 = memory[maddr_d + yhalf - delaym0];
- mis1 = memory[maddr_d + yhalf - delaym1];
- mis2 = memory[maddr_d + yhalf - delaym2];
- mis3 = memory[maddr_d + yhalf - delaym3];
-
- GRAFM = (mis0 & 0x03) | (mis1 & 0x0c) | (mis2 & 0x30) | (mis3 & 0xc0);
- }
- }
- }
-
- static void Clear_Border(int hscrol)
- {
- int scrol=HSCROL+HSCROL;
- int shift=FILLIN_OFFSET;
- int left=FILLIN_OFFSET+dmactl_xmin_noscroll;
-
- if (hscrol) {
- shift -= scrol;
- if ((DMACTL & 0x03)!=0x03)
- left -= scrol;
- }
-
- memset(scrn_ptr,PF_COLBK,left);
- memset(scrn_ptr+dmactl_xmax_noscroll+shift,PF_COLBK,
- ATARI_MODULO-dmactl_xmax_noscroll-shift);
- }
-
- static void ANTIC_Scanline(int dmacycles,int nmi,int hscrol,ModeFunc *gen,UBYTE *fillin,int width,int displayline)
- {
- int before;
- int after;
- int add;
-
- #ifdef DEBUG
- hpos=H_BEFORE_DMA;
- #endif
- before=cc_middle-before_dma-dmacycles;
- after=114-cc_middle-after_wsync;
- if (before<0) {
- after += before;
- before = 0;
- }
- add = carry;
- Clear_Border(hscrol);
- if (!wsync_halt) {
- if (before_dma>0)
- add = GO(before_dma+add);
- #ifdef DEBUG
- hpos=H_FIRST_HALF;
- #endif
- if (nmi) {
- before += add;
- before -= dli_delay;
- if (before>0) {
- NMI();
- nmi = FALSE;
- add = GO(before);
- }
- } else {
- before += add;
- if (before>0)
- add = GO(before);
- }
- }
- /* generate the display */
- (*gen)(fillin,width,displayline);
- pmg_dma ();
- Atari_ScanLine (hscrol);
- #ifdef DEBUG
- hpos=H_SECOND_HALF;
- if (nmi) {
- dlipos=ypos;
- dline=displayline;
- }
- #endif
- if (!wsync_halt) {
- if (nmi) {
- after += add;
- after -= dli_delay;
- if (after>0) {
- NMI();
- nmi = FALSE;
- add = GO(after);
- }
- } else {
- after += add;
- if (after>0)
- add = GO(after);
- }
- }
- #ifdef DEBUG
- hpos=H_AFTER_WSYNC;
- #endif
- wsync_halt=0;
- if (nmi) {
- NMI();
- add = GO(after_wsync-dli_delay+add);
- } else add = GO(after_wsync+add);
- carry = add;
-
- scrn_ptr += ATARI_MODULO;
- ypos++;
-
- }
-
-
- /* Generate one mode line of the ANTIC display.
- IR is the instruction code and only needed for horizontal/vertical scrolling
- and NMI generation. No jump codes are generated here.
- first is the first scan line of the mode line to be generated. It may be
- negative for artefacts. The first scan line is then generated over again
- until the counter gets zero.
- nlines is the number of scan lines in this mode line.
- last is the number of the last scan line to be generated. It may be larger
- than nlines. In this case, the last scan line is repeated over again to
- generate VSCROLL artefacts.
- acnt is the # of stealed DMA cycles for each scan line of the mode line
- acntn is the # of additional DMA cycles for the first scan line.
- ModeFunc * is the scan line generator function. It's called with the
- *fillin pointer, so to know where to place the graphics, the width
- of the scan line in half color clocks and the scan line of the mode line
- to be generated. */
-
- static void Antic_Modeline(int IR,int first,int last,int nlines,int dmashift,int dmaadd,ModeFunc *gen)
- {
- int width;
- int scanline;
- int displayline;
- int dmawidth;
- UBYTE *fillin;
- int dma;
- int nmi=FALSE;
-
- nlines--; /* for simpler calculations */
- for (scanline=first;scanline<=last;scanline++) {
- /* get the line to be displayed. */
- displayline=scanline;
- if (displayline<0)
- displayline = 0;
- if (displayline>nlines)
- displayline=nlines;
-
- /* Get the width of the line. Must be taken from DMACTL right now because
- the CPU may change it within the mode line */
-
- dmawidth = DMAwidth; /* DMA base cycle counter */
- width = dmawidth<<6; /* # of color clocks */
- fillin = scrn_ptr+dmactl_xmin_noscroll+FILLIN_OFFSET; /* graphics fill-in position */
-
- /* All that changes a lot if HSCROL is turned on. Get the next wider display */
-
- if (IR & 0x10) {
- fillin = scrn_ptr+dmactl_xmin_scroll+FILLIN_OFFSET;
- if (dmawidth<6) {
- dmawidth++;
- width += 64;
- dmaadd--; /* one memory refresh cycle is dropped */
- }
- }
-
- /* get the number of DMA cycles needed to display that mode */
-
- /* base cycles for DISPLAY DMA, used for character based DMA */
- if (dmashift)
- dma = dmawidth << dmashift;
- else dma = 0;
-
- /* add the memory refresh cycles */
- dma += 9;
-
- if ((DMACTL & 0x10) || (ypos & 0x01)==0)
- dma += pm_dma; /* turn on player DMA? */
-
- if (scanline==first)
- dma += dmaadd; /* add the DMA cycles to get this mode line IR */
-
- /* keep track of the DLI if turned on */
- if ((scanline == last) && (IR & 0x80)) {
- if (NMIEN & 0x80) {
- NMIST = 0x80;
- nmi = TRUE;
- }
- }
-
- /* run the scancode */
- ANTIC_Scanline(dma,nmi,IR & 0x10,gen,fillin,width,displayline);
- }
- }
-
- void ANTIC_RunDisplayList (void)
- {
- int JVB=FALSE;
- int nlines=0;
- int width;
- int IR;
- int dmabase;
- int dmawidth;
- int dmashift;
- int vertthis,vertlast;
- ModeFunc *gen; /* scanline generator. Requires fill-in position,
- width in half color clocks and scan line within
- the mode line to be build */
-
- wsync_halt = 0;
- vertthis=FALSE;
- vertlast=FALSE;
- gen = NULL;
-
- /*
- * VCOUNT must equal zero for some games but the first line starts
- * when VCOUNT=4. This portion processes when VCOUNT=0, 1, 2 and 3
- */
-
- scrn_ptr = (UBYTE*)atari_screen;
-
- DLIST=DLISTINIT;
- for (ypos = 0; ypos <8 ;ypos++) {
- carry=GO (carry+105); /* 114 minus 9 memory cycles */
- }
-
- NMIST = 0x00;
-
- for (ypos = 8, JVB=FALSE ; ypos < (ATARI_HEIGHT + 8);) {
-
- /* Counter needed for the DMA cycles to fetch display instructions */
- dmabase = 0;
-
- /* vertical scroll flags. */
- vertlast=vertthis;
- vertthis=FALSE;
-
- /* setup base DMA width. Changed for HSCROL */
- dmawidth = DMAwidth;
-
- /* display width */
- width = dmawidth<<6;
-
- gen = NULL;
- /* scan line generator. Needs to be called for each scan line
- to be generated. */
-
- /* dmawidth must be shifted by this to get the DMA display cycles */
- dmashift = 0;
-
- if (JVB || (DMACTL & 0x20)==0) {
- ANTIC_Scanline(9,FALSE,FALSE,&Build_Blank,scrn_ptr,ATARI_MODULO,0);
- } else {
- IR = APeek(DLIST);
- DLIST++;
- dmabase++;
-
- switch (IR & 0x0f)
- {
- case 0x00 :
- nlines = ((IR >> 4) & 0x07) + 1;
- gen = &Build_Blank;
- IR &= 0x80; /* avoid confusion with scrolling flags */
- break;
- case 0x01 :
- if (IR & 0x40)
- JVB = TRUE;
- DLIST = DAPeek(DLIST);
- dmabase += 2;
- nlines = 1;
- gen = &Build_Blank; /* Jump aparently uses 1 scan line */
- IR &= 0x80;
- break;
- default :
- if (IR & 0x40) {
- screenaddr = DAPeek(DLIST);
- DLIST += 2;
- dmabase += 2;
- }
-
- /* Keep track of vertical scrolling */
- if (IR & 0x20) {
- vertthis = TRUE;
- }
-
- if (IR & 0x10) {
- if (dmawidth<6) {
- dmawidth++;
- width += 64;
- }
- }
-
- switch (IR & 0x0f) {
- case 0x02 :
- nlines = 8;
- dmashift = 3; /* dmawith * 8 */
- dmabase += (dmawidth<<3)+memory_basis-9; /* reduce memory DMA */
- gen = Antic_2(width);
- break;
- case 0x03 :
- nlines = 10;
- dmashift = 3;
- dmabase += (dmawidth<<3)+memory_basis-9;
- gen = Antic_3(width);
- break;
- case 0x04 :
- nlines = 8;
- dmashift = 3;
- dmabase += (dmawidth<<3)+memory_basis-9;
- gen = Antic_4(width);
- break;
- case 0x05 :
- nlines = 16;
- dmashift = 3;
- dmabase += (dmawidth<<3)+memory_basis-9;
- gen = Antic_5(width);
- break;
- case 0x06 :
- nlines = 8;
- dmashift = 2;
- dmabase += (dmawidth<<2);
- gen = Antic_6(width);
- break;
- case 0x07 :
- nlines = 16;
- dmashift = 2;
- dmabase += (dmawidth<<2);
- gen = Antic_7(width);
- break;
- case 0x08 :
- nlines = 8;
- dmabase += (dmawidth<<1);
- gen = Antic_8(width);
- break;
- case 0x09 :
- nlines = 4;
- dmabase += (dmawidth<<1);
- gen = Antic_9(width);
- break;
- case 0x0a :
- nlines = 4;
- dmabase += (dmawidth<<2);
- gen = Antic_A(width);
- break;
- case 0x0b :
- nlines = 2;
- dmabase += (dmawidth<<2);
- gen = Antic_B(width);
- break;
- case 0x0c :
- nlines = 1;
- dmabase += (dmawidth<<2);
- gen = Antic_C(width);
- break;
- case 0x0d :
- nlines = 2;
- dmabase += (dmawidth<<3);
- gen = Antic_D(width);
- break;
- case 0x0e :
- nlines = 1;
- dmabase += (dmawidth<<3);
- gen = Antic_E(width);
- break;
- case 0x0f :
- nlines = 1;
- dmabase += (dmawidth<<3);
- gen = Antic_F(width);
- break;
- default :
- printf("Antic.c: IR %x caused problems.\n",IR);
- nlines = 0;
- break;
- }
- break;
- }
-
- if (nlines > 0) {
- int first,last;
-
- if (gen) {
- /* Calculate the first & last line to display */
- first = 0;
- last = nlines-1;
-
- /* If this is a VScrol-Line, delay the first line. */
- if (vertthis && !vertlast) {
- first = VSCROL;
- if (first>last)
- first -= 16;
- }
- if (!vertthis && vertlast) {
- last = VSCROL+1;
- }
-
- Antic_Modeline(IR,first,last,nlines,dmashift,dmabase,gen);
- } else {
- printf("Antic.c: Found unknown mode generator.\n");
- }
- }
- }
- }
-
- for(ypos=248; ypos<vsync_pos;ypos++)
- carry = GO(carry+105);
-
- NMIST = 0x40; /* Set VBLANK */
- if (NMIEN & 0x40) {
- carry=GO (carry+7);
- /* Needed for programs that monitor NMIST (Spy's Demise, GORF) */
- NMI ();
- carry -= dli_delay+7; /* Needed by 6502 to react */
- }
-
- if (tv_mode == PAL)
- for (ypos=vsync_pos;ypos<312;ypos++)
- carry=GO (carry+105);
- else
- for (ypos=vsync_pos;ypos<262;ypos++)
- carry=GO (carry+105);
- }
-
-